from __future__ import annotations

from datetime import date
from typing import Optional, Tuple

try:
    from zhdate import ZhDate  # type: ignore
except Exception:  # pragma: no cover - 可选依赖
    ZhDate = None  # noqa: N816


def get_next_lunar_anniversary(lunar_year: int, lunar_month: int, lunar_day: int, today: date) -> Tuple[date, int]:
    """计算下一个农历周年日期，返回(下次公历日期, 对应农历年份)。"""
    if ZhDate is None:
        raise RuntimeError("zhdate 未安装，无法计算农历日期")

    next_anniversary: Optional[date] = None
    while next_anniversary is None or next_anniversary < today:
        try:
            next_anniversary = ZhDate(lunar_year, lunar_month, lunar_day).to_datetime().date()
            if next_anniversary < today:
                lunar_year += 1
        except Exception:
            lunar_year += 1
    return next_anniversary, lunar_year


def get_next_solar_anniversary(event_month: int, event_day: int, today: date) -> date:
    """计算下一个公历周年日期。处理 2/29 情况。"""
    this_year = today.year
    next_anniversary: Optional[date] = None

    while next_anniversary is None or next_anniversary < today:
        try:
            next_anniversary = date(this_year, event_month, event_day)
        except ValueError:
            if event_month == 2 and event_day == 29:
                next_anniversary = date(this_year, 3, 1)
        if next_anniversary is None or next_anniversary < today:
            this_year += 1
    return next_anniversary


def calculate_next_anniversary_single(anniversary_date: date, is_lunar: bool) -> Optional[dict]:
    """计算单个事件的下一个周年日期，返回派生字段字典。"""
    today = date.today()
    try:
        year, month, day = anniversary_date.year, anniversary_date.month, anniversary_date.day
        if is_lunar:
            next_anniversary, next_lunar_year = get_next_lunar_anniversary(year, month, day, today)
            delta = (next_anniversary - today).days
            next_occurrence = (next_lunar_year - year - 1) if next_anniversary > today else (next_lunar_year - year)
        else:
            next_anniversary = get_next_solar_anniversary(month, day, today)
            delta = (next_anniversary - today).days
            next_occurrence = (next_anniversary.year - year - 1) if next_anniversary > today else (next_anniversary.year - year)

        return {
            "next_anniversary": next_anniversary.strftime("%Y-%m-%d"),
            "days_until_next_anniversary": delta,
            "is_lunar": is_lunar,
            "original_date": anniversary_date.isoformat(),
            "next_occurrence": max(0, next_occurrence),
        }
    except Exception:
        return None


